React-[作業篇]-W2 | 產品CRUD練習


Posted by suihsilan on 2023-08-22

前言

六角學院的React入門工作坊進入第二週了,看到很多同學紛紛都將作業交上去了,我還不是很熟練,就很感謝DC同學分享自己的筆記與思路,才覺得我先前拆解同學的code分析成邏輯流程的方式是對的,然後自己重新在撰寫一次,這次也是一樣的模式!

第二週作品

大佈局:資料狀態 與 介面

在開始動工之前,先來思考會有什麼資料會需要使用到呢?不知道要放什麼資料,可以從功能開始,因為會有資料,就是因為有使用的需求呀!

產品列表

  • 描述:需要有“產品原始資料”,我要運用這筆資料,將產品列表渲染到畫面上
  • 設定資料狀態:const [productList, setProductList] = useState()
  • 功能:
    • 根據畫面的“click”,會把被點擊的產品資料(id,品項,描述,價格)等資料丟到購物車中
    • 點擊的品項,如果已經在購物車中了,就要把已存在在購物車資料中的該品項的數量資料+1

購物車列表

  • 描述:會需要有“購物車資料”,一開始購物車資料是空陣列,因為還沒購物XD
  • 設定資料狀態:
    const [cart, setCart] = useState([]);
    const [sum, setSum] = useState(0);
    const [note, setNote] = useState(“”)

  • 功能:

    • 我們在點擊產品列表的某品項之後,該品項會被加入到“購物車資料”中,然後進行渲染購物車畫面
    • 在購物車畫面的顯示裡,該品項除了產品的基本資料(id,品項名,描述,價格),在購物車資料中,要多定義“數量”與小計(數量*價格)
    • 刪除按鈕:當我們不想要該品項時,可以透過刪除按鈕,將該品項刪除
    • 更新數量:前面有敘述過,可以直接手動調整訂購的產品的數量
    • 購物車品項的全部消費加總->需要定義資料狀態const [sum, setSum] = useState(0);
    • 備註也需要另外定義資料狀態const [note, setNote] = useState(“”)
    • 點擊送出訂單按鈕時,會將購物車資料帶到訂單畫面中

訂單列表

  • 描述:會需要原始訂單資料,初始狀態是空陣列,接到從“購物車“送出按鈕後,送過來的資料
  • 設定資料狀態:
    const [order, setOrder] = useState([])
  • 除了從購物車帶來的資料,要多定義一個id

介面的部分:

這次先純以“熟練React功能”為主,暫時先以bootstrap切版


撰寫程式邏輯

1-1 將產品資料渲染到畫面上

  • App元件
  • Menu元件,已經透過props將productList傳給Menu元件使用,透過資料驅動的方式將productList.map渲染到畫面上,記得要帶上key值

1-2 點擊畫面上的飲品時,會將資料帶入購物車

  • 寫入購物車資料,預設為[] const [cart, setCart] = useState([]);
  • 點擊畫面上的飲品
    • 為每個飲品,加入onClick事件->觸發函式addCart fn
      • 撰寫函式addCart邏輯,addCart要帶入參數(product),也就是productList中的“被點擊的品項”,每個飲品都有可能被點擊,所以都加上
    • 在addCart fn寫一個tempCart的新陣列,也就是為被點擊的品項做資料重組的動作,並給product帶入qty屬性預設值為1
  • addCart fn的流程設計

      const addCart = (product) => {
          //短暫被加入的購物車資料(幫我做被點擊的品項的資料重組)
          const tempCart = [
          ...cart, //[]帶入購物車原始資料,淺拷貝
          {
            ...product,//帶入被點擊的品項原始資料
            qty: 1, //給該品項資料增加qty屬性
            //被帶入的品項數量預設都為1
          }
        ]
        //寫入購物車資料
        setCart(tempCart);
      }
    
  • App元件:圖片上cart的props其實不用帶入到Menu元件,因為Menu元件不會使用到

  • Menu元件
  • 加入購物車資料的console

1-3 將購物車資料渲染到畫面

  • 購物車元件

1-4 判斷購物車是不是空的,切換畫面

  • hint: 當然就需要透過購物車資料來判斷
    • cart.length === 0 來判斷要顯示的畫面
    • 這段在寫的時候一直出錯.後來才知道犯了JSX語法錯誤

1-5 重複點選飲品的判斷

當我在產品列表畫面點擊的品項,如果已經在購物車中了,就要把已存在在購物車資料中的該品項的數量資料+1

  • 分析:點擊品項時,會先將該品項去跟購物車資料做判斷,判斷說是否已有該品項了
    • 無該品項 -> 將該品項加入到購物車(本來就寫好的邏輯)
      • 在購物車資料中用.find or .findIndex比對資料
      • 這裡我們只需要知道"有或沒有"用.findIndex就好
      • 沒有會回傳-1
    • 有該品項 -> 更新該品項數量
      • 重組tempCart的資料,將cart購物車資料拉出來比對是哪一項,
      • 將該項資料的數量值更新值

1-6 購物車價格總計算

定義購物車商品的價格總計const [sum, setSum] = useState(0)來總計商品的總價,然後透過useEffect來觀察購物車是否有更動,只要畫面更動就透過.reduce()方法來總計

  • 記得要將sum透過props傳到購物車元件上
  • 才能在購物車上渲染畫面

1-7 購物車品項手動select更改數量

這段功能是在描述,我可以在購物車清單畫面上手動的調整,該品項數量的select值,進而更新其他相關的值

我沒有在select標籤上綁value值,但沒有另外搭配onChange事件時,程式可以運作,但會一直出現紅字訊息如下,然後select區塊無法手動操作

首先,我在select上綁定value以及相關的資料狀態

給表單型態的標籤,加入onChange事件,撰寫函式updateCart程式邏輯並帶入參數(被更新的品項,e.target.value)

    const updateCart = (updateItem, value) => {
        //設置tempData來比對在購物車資料中哪一個品項被更新數量了
        const tempData = cart.map((cartItem) => {
            return cartItem.id === updateItem.id
            ? {
                ...cartItem,
                qty: Number(value), //表單中所有的值都是字串需要轉型
            }
            : {...cartItem}
        });
        setCart(tempCart)
    }


1-8 刪除購物車品項

當我們在購物車清單畫面上,點擊該品項前面的刪除按鈕,就可以刪除該品項,這裡會用.filter的方式寫:

  • 要在按鈕上加入onClick事件,撰寫函式deleteCart刪除邏輯
    note: cartItem.id !== deleteItem.id 只要該品項不等於[被點擊刪除按鈕的]品項,那個該品項就會被保留下來
  • 這裡會需要轉想一下,但仔細想filter就是一個過濾器,只要“符合我們設定過濾器的條件”就會被回傳出來,也就是說會被留下來
    const deleteCart = (deleteItem) => {
      const tempCart = cart.filter((cartItem) => cartItem.id !== deleteItem.id)
      setCart(tempCart)
    }
    

1-9 創建訂單(待捕)

甚麼是創建訂單呢?就是說,我在購物車畫面上,已經選購好商品,就點擊購物車列表的按鈕,所以要設置onClick事件,觸發函式:createOrder
會需要定義資料const [order, setOrder] = useState([]);以及const [note, setNote] = useState([]);

  • 還需要設置:在備註的表單上取的e.target.value備註 value的值
  • 所以訂單上,我們會需要什麼資料?
    • 新的id:代表該筆訂單
    • 購物車資料cart
    • 備註資料note
    • 總價格sum
    • 最後,生出訂單後,我們要清空購物車以及備註欄位

1-10 將訂單資料渲染到畫面上

這裡購物車開始的邏輯很像,就是先判斷order.length === 0
判斷訂單資料是不是空的:
如果是就顯示尚未建立訂單
如果不是就直接渲染資料 -> 資料驅動


#React學習 #React購物車功能 #crud







Related Posts

陳述式 與 表達式

陳述式 與 表達式

redis 套件的 Property 'on' does not exist on type 'RedisClientType'

redis 套件的 Property 'on' does not exist on type 'RedisClientType'

Switch between uppercase to lowercase

Switch between uppercase to lowercase


Comments